/**
 * Created by Mic on 16/2/23.
 */

var DeskCharacter = require('./deskCharacter');
var util = require('util');
var logger = require('pomelo-logger').getLogger(__filename);
var consts = require('../../consts/consts');
var Poker = require('../poker/poker');
var _ = require('underscore');
var pomelo = require('pomelo');

var Desk = function (opts) {
    DeskCharacter.call(this, opts);

    this.tomsg = function () {
        return {
            curTalkIndex: this.curTalkIndex,
            playerList: this.playerPool.getPlayersBaseInfo(),
            dipai: this.dipai,
            ondesk: this._ondesk,
            dizhu: this.dizhu,
            baseBet: this.baseBet,
            beishu: this.getBeishu(),
            playValue: this.playValue,
            playIndex: this.playIndex
        }
    };
};

util.inherits(Desk, DeskCharacter);
module.exports = Desk;

var handler = Desk.prototype;

//更新信息
handler.updateDeskInfo = function () {
    this.pushMsg2All('onUpdateDesk', this.tomsg());

    var deskStatus = _.compact(this.playerList);
    if (deskStatus.length == 3) {
        this.setStatus(consts.Desk.Status.Full);
    }
    this.checkAllReady();

    //添加机器人
    if (!!this.timingId) {
        clearTimeout(this.timingId);
    }
    var self = this;
    if (this.status == consts.Desk.Status.NotFull && this.robot) {
        var time = 2 + Math.random() * 1;
        this.timingId = setTimeout(function () {
            console.error('添加机器人成功1');
            self.addRobot();
        }, time * 1000);
    }
    else {
        if (this.status == consts.Desk.Status.AllReady) {
            logger.debug('桌子齐了,开始游戏');
            this.startGame();
        }
    }
};

handler.ready = function (playerInfo, value) {
    if (playerInfo.money < this.money) {
        return consts.Player.Status.Desk_Money_No;
    }
    logger.fatal(playerInfo.uuid + '准备了');
    this.playerPool.ready(playerInfo, value);
    this.checkAllReady();

    if (this.status == consts.Desk.Status.AllReady) {
        logger.debug('都准备好了1 ');
        this.startGame();
    }
    return consts.Code.Ok;
};
handler.readyResult = function (seatIndex, value) {
    this.pushMsg2All('on_ready_result', {seatIndex: seatIndex, value: value});
    this.checkAllReady();
    var self = this;

    //添加机器人 如果有两个人已经准备了 则添加机器人
    var curPlayerList = _.compact(this.playerList);

    if (curPlayerList.length == 2 && this.status == consts.Desk.Status.NotFull && this.robot) {
        logger.fatal('准备添加机器人 ' + curPlayerList.length + (curPlayerList.length == 2));
        this.timingId = setTimeout(function () {
            console.error('添加机器人成功2');
            self.addRobot();
        }, 2 * 1000);
    } else {
        if (this.status == consts.Desk.Status.AllReady) {
            console.error('准备完了开始游戏???', this.playerList);
            this.startGame();
        }
    }
};

//检查是否全部准备了,if all ready,game begin.
handler.checkAllReady = function () {
    var flag = this.playerPool.checkAllReady();
    if (flag && !this._start) {
        this.setStatus(consts.Desk.Status.AllReady);
    }
};

//初始化牌
handler.initPokers = function (robotArr) {
    var poker = new Poker();
    poker.addPacks(1, 0);
    //return poker.shuffle()._cards;
    return poker.bombCard(robotArr);
};
//发牌
handler.deliverCards = function () {
    console.log('正在发牌 ', this.playerKind);
    var cards = this.initPokers(this.playerKind);

    //var cardsArr = [[], [], []];
    //
    //for (var i = 0; i < 17; i++) {
    //    for (var j = 0; j < this.MAX_MEMBER_NUM; j++) {
    //        cardsArr[j].push(cards.shift());
    //    }
    //}
    //this.dipai = cards;

    //做牌的
    this.dipai = cards.pop();
    var self = this;
    _.each(this.playerList, function (p, i) {
        if (p) {
            var player = self.getPlayerBySeatIndex(p.seatIndex);
            player.addCards(cards.shift());
            //log.log(player.getCards());
        }
    });
    setTimeout(function () {
        self.pushMsg2All('on_deliver', self.tomsg());
    }, 1000);
};
handler.startGame = function () {
    if (this._start)return;
    this._start = true;
    this.setStatus(consts.Desk.Status.Gaming);
    console.error('开始游戏 ', this.getStatus());

    var self = this;
    //扣服务费
    this.playerPool.deskFee(this.deskFee(), function () {
        console.log("桌子费已经扣除...");
        self.pushMsg2All("on_deskFee", {ticket: self.deskFee()});
    });

    //发牌
    this.deliverCards();
    //通知叫地主
    var seatIndex = parseInt(Math.random() * 3);
    setTimeout(function () {
        self.jiao(seatIndex);
    }, 3000);
};
handler.jiao = function (index) {
    this.curTalkIndex = index;
    var player = this.playerPool.getPlayerByIndex(index);
    player.jiao();
    this.pushMsg2All('on_jiao', {seatIndex: this.curTalkIndex});
    this.recordRoute('on_jiao', this.curTalkIndex, consts.Desk.Time.Jiao);

    //超时处理
    this.timingId = setTimeout(function () {
        player.autoJiao();
    }, consts.Desk.Time.Jiao * 1000);
};
handler.jiaoResult = function (index, value) {
    if (this.timingId) {
        clearInterval(this.recordTimer);
        clearTimeout(this.timingId);
    }
    if (index != this.curTalkIndex % 3) {
        logger.error('叫地主出错');
        return;
    }

    logger.fatal(this.curTalkIndex + '是否叫地主 ' + value);
    this.pushMsg2All('on_jiao_result', {seatIndex: this.curTalkIndex, value: value});

    if (!!value) {
        this.qiangResultArr.push(index);
        this.dizhuMark = index;
        this.recordData(consts.Desk.Record.Jiao, index);

        if (this.noPointCount == 2) {
            logger.fatal('直接选出地主来了 ' + this.dizhuMark);
            this.choseDizhu(this.dizhuMark);
        } else {
            //开始抢地主
            this.curTalkIndex++;
            this.qiang(this.curTalkIndex);
        }
    } else {
        this.recordData(consts.Desk.Record.UnJiao, index);

        this.noPointCount++;
        //设置player不能抢地主
        var noJiaoIndex = this.curTalkIndex;
        var player = this.playerPool.getPlayerByIndex(noJiaoIndex);
        player.setCantQiang(true);

        //判断是否能继续叫地主
        if (this.noPointCount == 3) {
            console.warn('都不叫地主,重新发牌 ' + this.qiangResultArr);
            this.reset();
            this.startGame();
        } else {
            this.curTalkIndex++;
            this.jiao(this.curTalkIndex);
        }
    }
};
handler.qiang = function (index) {
    this.curTalkIndex = index;
    this.qiangCount++;
    var player = this.playerPool.getPlayerByIndex(index);
    var cant = player.getCantQiang();

    if (cant) {
        logger.fatal('你不能抢地主 ' + index % 3);
        return false;
    } else {
        player.qiang();
        this.pushMsg2All('on_qiang', {seatIndex: this.curTalkIndex});
        this.recordRoute('on_qiang', this.curTalkIndex, consts.Desk.Time.Qiang);

        //超时处理
        this.timingId = setTimeout(function () {
            player.autoQiang();
        }, consts.Desk.Time.Qiang * 1000);

        return true;
    }
};
handler.qiangResult = function (index, value) {
    if (!!this.timingId) {
        clearTimeout(this.timingId);
        clearInterval(this.recordTimer);
    }
    if (index != this.curTalkIndex % 3) {
        logger.error('抢地主出错');
        return;
    }

    this.pushMsg2All('on_qiang_result', {seatIndex: this.curTalkIndex, value: value});

    if (!!value) {
        this.recordData(consts.Desk.Record.Qiang, index);

        this.qiangResultArr.push(index);
        this.dizhuMark = index;
        this.setBeishu(2);
        //log.log(index + ' 抢地主加倍 ' + this.beishu);
        //this.pushMsg2All('on_jiabei', {test: '抢地主加倍 ' + this.beishu});

    } else {
        this.recordData(consts.Desk.Record.UnQiang, index);

        this.noPointCount++;
    }

    //判断是否能选出地主
    if (this.noPointCount == 2 || this.qiangCount == 3 || (this.qiangResultArr.length > 1 &&
        (_.first(this.qiangResultArr) == _.last(this.qiangResultArr)))) {
        logger.trace('选出地主了 ' + this.dizhuMark);
        this.choseDizhu(this.dizhuMark);
    } else {
        this.curTalkIndex++;
        var can = this.qiang(this.curTalkIndex);
        if (!can) {
            this.curTalkIndex++;
            this.qiang(this.curTalkIndex);
        }
    }
};
handler.choseDizhu = function (dizhuIndex) {
    this.dizhu = dizhuIndex;
    this.curTalkIndex = dizhuIndex;
    this.qiangCount = 0;
    this.playerPool.notifyDizhu(dizhuIndex, this.dipai);
    this.clearRecordData();

    //log.log('底牌 ' + this.dipai);
    var self = this;
    setTimeout(function () {
        self.pushMsg2All('on_dizhu', self.tomsg());
        self.double();
    }, 500);
};
handler.double = function () {
    var self = this;
    setTimeout(function () {
        self.playerPool.notifyDouble();
        self.pushMsg2All('on_double', self.tomsg());
    }, 1000);
    this.clearRoute();
};
handler.doubleResult = function (index, value) {
    this.qiangCount++;
    var player = this.playerPool.getPlayerByIndex(index);
    //player.setDoubleStatus(value);
    player.notifyDouble(value);

    this.recordData(value, index);
    this.pushMsg2All('on_double_result', {seatIndex: index, value: value});

    //判断地主加倍
    if (value && index == this.dizhu) {
        this.setBeishu(2);
        //log.log('地主加倍了所以加倍 ' + this.beishu);
        //this.pushMsg2All('on_jiabei', {test: '地主加倍' + this.beishu});
    }

    //判断加倍结束
    if (this.qiangCount == 3) {
        logger.fatal('加倍结束,开始出牌');
        this.clearRecordData();
        var self = this;
        setTimeout(function () {
            self.askPlay(self.dizhu);
        }, 1000);
    }
};
//args =>  位置 | 桌上的牌 | 自己剩余的牌 | 地主位置 | pass的个数 | 所有剩余的牌 (为了配合机器人)
handler.askPlay = function (index) {
    var dizhu = this.dizhu;
    var pass = this._pass;
    var ondesk = this._ondesk;
    var remains = this.getRemainsCards();
    var remainsArr = this.playerPool.getRemainsCard(index);

    //this.playerPool.notifyPlay(index, ondesk, remainsArr, dizhu, pass, remains);
    var player = this.playerPool.getPlayerByIndex(index);
    player.notifyPlay(index, ondesk, remainsArr, dizhu, pass, remains);

    this.pushMsg2All('on_play', this.tomsg());
    this.recordRoute('on_play', this.curTalkIndex, consts.Desk.Time.Play - 2);

    //超时处理
    this.timingId = setTimeout(function () {
        console.log("通知出牌 ");
        player.autoPlay(index, ondesk, remainsArr, dizhu, pass, remains);
    }, consts.Desk.Time.Play * 1000);
};
handler.playResult = function (index, value) {
    //console.error(index + '出牌了  ' + value + ' ' + this.curTalkIndex % 3);
    if ((index % 3) != (this.curTalkIndex % 3))return;
    if (!!this.timingId) {
        clearTimeout(this.timingId);
        clearInterval(this.recordTimer);
    }
    if (this._pass == 0 && this._ondesk == [] && (value == null || value.length == 0)) {
        logger.fatal(this.curTalkIndex % 3 + ' 必须出');
        var player = this.playerPool.getPlayerByIndex(index);
        var cards = player.getCards();
        value = cards[cards.length - 1];
    }

    this.playerPool.playedCards(index, value);
    var msg = this.tomsg();
    msg['value'] = value;

    this.recordData(value, index);
    this.pushMsg2All('on_play_result', msg);


    if (value == null || value.length == 0) {
        this._pass++;
        if (this._pass == 2) {
            logger.fatal('两家过,你出' + this.curTalkIndex);
            this._ondesk = [];
            this._pass = 0;
        }
    } else {
        this._pass = 0;
        this._ondesk = value;

        var type = Poker.getCardType(value).type;
        if (type == 'rocket' || type == 'bomb') {   //还要判断炸弹
            this.setBeishu(2);
            //log.log(index + type + ' 炸弹加倍 ' + value + '   ' + this.beishu);
            //this.pushMsg2All('on_jiabei', {test: type + ' 炸弹加倍 ' + this.beishu});
        }
    }
    //检查是否游戏结束
    //var isOver = this.checkGameOver();
    //if (isOver)return;
    //
    //this.curTalkIndex++;
    //this.askPlay(this.curTalkIndex);
    var self = this;
    this.checkGameOver(function () {
        self.curTalkIndex++;
        self.askPlay(self.curTalkIndex);
    });
};
handler.hosting = function (player) {
    var hostingPlayer = this.playerPool.getPlayerByUuid(player.uuid);
    if (!hostingPlayer) {
        return;
    }
    hostingPlayer.hosting();
    this.pushMsg2All('on_hosting', {seatIndex: hostingPlayer.seatIndex});
};
handler.unHosting = function (player) {
    var unHostingPlayer = this.playerPool.getPlayerByUuid(player.uuid);
    unHostingPlayer.unHosting();
    this.pushMsg2All('on_unHosting', {seatIndex: unHostingPlayer.seatIndex});
};
handler.getRemainsCards = function () {
    this._remainsCards = this.playerPool.getRemainsCards();
    return this._remainsCards;
};
handler.checkGameOver = function (callback) {
    var isOver = this.playerPool.checkGameOver(this.dizhu);
    if (!!isOver) {
        if (!!this.timingId) {
            clearTimeout(this.timingId);
        }
        var msg = {
            spring: null,
            gameCoins: null,
            deskBeishu: null
            //bombCounts:null,   //炸弹个数
        };
        //根据返回的是否春天 结算
        if (isOver.spring == consts.Desk.Code.Dizhu_spring
            || isOver.spring == consts.Desk.Code.Farmer_spring) {
            //春天了
            this.setBeishu(2);
            //log.log('春天加倍了 ' + this.beishu);
        }
        var winIndex = isOver.winIndex == this.dizhu ? consts.Desk.Code.Dizhu_win : consts.Desk.Code.Farmer_win;
        msg.gameCoins = this.playerPool.getGameCoins(winIndex, this.dizhu, this.getBeishu(), this.baseBet);
        msg.spring = isOver.spring;
        msg.deskBeishu = this.getBeishu();
        var info = this.tomsg();
        info['overInfo'] = msg;

        var self = this;
        setTimeout(function () {
            self.pushMsg2All('on_gameOver', info);
            self.reset();
        }, 1500);

        this.setStatus(consts.Desk.Status.Full);

        //如果没准备的 超过15s就把它踢出
        this.kickNotReady();

        //return true;
    } else {
        callback();
    }
    //return false;
};
//强退 机器人代打
handler.playerDisconnect = function (playerInfo) {
    var player = this.playerPool.getPlayerByUuid(playerInfo.uuid);
    if (!!player) {
        console.error(this.name, ' 掉线了');
        player.disconnect();

        //可能要发送托管标志
        this.pushMsg2All('on_disconnect', {seatIndex: player.seatIndex});
    }
};
handler.playerConnected = function (playerInfo) {
    var player = this.playerPool.getPlayerByUuid(playerInfo.uuid);
    if (!!player) {
        logger.fatal('玩家连上了 ' + playerInfo.uuid);
        player.connect();
        this.pushMsg2All('on_connect', {seatIndex: player.seatIndex});
        var self = this;
        this.playRoute.uuid = playerInfo.uuid;
        this.playRoute.time = this.playTime;
        setTimeout(function () {
            self.pushMsg2All('on_test', self.playRoute);
        }, 1500);
        return this.tomsg();
    }
};
handler.reConnect = function (playerInfo) {
    var player = this.playerPool.getPlayerByUuid(playerInfo.uuid);
    if (!!player) {
        player.connect();
        this.pushMsg2All('on_connect', {seatIndex: player.seatIndex});
    }
};
//正常离开桌子
handler.leave = function (playerInfo) {
    playerInfo = this.playerPool.getPlayerByUuid(playerInfo.uuid);
    this.playerPool.leave(playerInfo);
    this.playerList[playerInfo.seatIndex] = null;

    this.pushMsg2All('on_leave', this.tomsg());
    this.removePlayerFromChannel(playerInfo);
    this.setStatus(consts.Desk.Status.NotFull);

    var self = this;
    //1,看下有没有准备
    var readyCounts = 0;

    _.each(_.compact(this.playerPool.playerList), function (p) {
        if (p && p.readyStatus) {
            readyCounts++;
        }
    });
    //如果没人或者有一个人但是没有准备 则删除桌子
    if (_.compact(this.playerPool.playerList).length == 0) {
        this.removeThisDesk();
    } else if (_.compact(this.playerPool.playerList).length == 1
        && readyCounts == 0) {
        this.removeThisDesk();
    } else if (readyCounts >= 1 && this.robot) {
        //怎么样添加机器人 如果是真人的话不用管他
        console.log('能不能添加机器人啊');
        this.timingId = setTimeout(function () {
            console.log('添加机器人了');
            self.addRobot();
        }, 2000);
    }
};
//踢出没有准备的
handler.kickNotReady = function () {
    var self = this;
    //1,得到未准备的
    var notReadyPlayers = null;
    this.timingId = setTimeout(function () {
        notReadyPlayers = self.playerPool.kickNotReady();
        _.each(notReadyPlayers, function (p) {
            logger.info('你该走了 ' + p);
            self.leave(p);
        });
    }, 1000 * 20);
};
//删除当前的desk  //先这样写着 可能有问题
handler.getDisPlayer = function () {
    return this.playerPool.getDisPlayer();
};
handler.removeThisDesk = function () {
    logger.fatal('remove this desk');
    console.log(this.timingId);
    if (!!this.timingId) {
        logger.info('clear desk time out');
        clearTimeout(this.timingId);
    }
    var disPlayer = this.getDisPlayer();
    pomelo.app.rpc.room.roomRemote.removeDesk({serverId: this.serverId},
        {roomName: this.roomName, deskName: this.name}, disPlayer, function (err, msg) {
            console.log(msg);
            if (msg.code == 200) {
                console.log('ok');
            }
        });
};

//桌子费用
handler.deskFee = function () {
    return this.ticket;
};
//记录桌子
handler.recordData = function (value, index) {
    this.playValue.push(value);
    this.playIndex.push(index);
};
handler.clearRecordData = function () {
    this.playValue = [];    //玩家的操作
    this.playIndex = [];    //对应的玩家的位置
};
//记录发生的广播
handler.recordRoute = function (route, seatIndex, time) {
    this.playRoute.route = route;
    this.playRoute.seatIndex = seatIndex;

    //开始倒计时
    this.playTime = time;
    var self = this;
    this.recordTimer = setInterval(function () {
        if (self.playTime > 0) {
            self.playTime--;
        } else {
            clearInterval(self.recordTimer);
        }
    }, 1000);

};
handler.recordTime = function () {

};
handler.clearRoute = function () {
    this.playRoute.route = null;
    this.playRoute.seatIndex = null;
    this.playTime = 0;
    clearInterval(this.recordTimer);
};

handler.test = function (name, userId, scode) {
    this.pushMsg2All("on_look", {name: name, userId: userId, scode: scode});
};